package ua.com.softway.mail;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import ua.com.softway.date.DateTime;
import ua.com.softway.db.date.DateTimeType;
import ua.com.softway.db.date.DateType;

/**
 * Mail account for sending messages
 */
@Entity
@Table(name="mail_account")
@TypeDefs({
   @TypeDef(name="swDate", typeClass=DateType.class),
   @TypeDef(name="swDateTime", typeClass=DateTimeType.class)
})
public class MailAccount {
    @Id @GeneratedValue(strategy=GenerationType.TABLE)
    public int id;
    
    @Column(name="ffrom")
    public String from;
    
    public String login;
    
    public String password;
    
    public String smtpHost;
    
    @Column(name="sssl")
    public boolean ssl;
    
    public int sent;
    
    @Type(type="swDateTime")
    public DateTime last;

    public boolean send(GeneratedMessage msg) throws MessagingException {
        Session session = getSession();
        if (session == null) throw new MessagingException("No mail session");

        MimeMessage mimeMessage = msg.createMimeMessage(this, session);
        mimeMessage.addHeader("X-GeneratedMessage-Id", "" + msg.id);
        Transport.send(mimeMessage);
        
        msg.state = GeneratedMessage.Sent;
        msg.sent = DateTime.now();
        
        sent ++;
        last = DateTime.now();
        
        return true;
    }
    
    private Session getSession() {
        Properties props = new Properties();
        
        props.setProperty("mail.transport.protocol", "smtp");  
        props.setProperty("mail.host", smtpHost);  
        
        if (password == null)
            return Session.getInstance(props);
        
        // SMTP authorization enabled
        props.put("mail.smtp.auth", "true");
        
        props.setProperty("mail.smtp.quitwait", "false");
        props.setProperty("mail.smtp.dsn.notify", "FAILURE");

        if (ssl) {
            props.put("mail.smtp.port", "465");  
            props.put("mail.smtp.socketFactory.port", "465");  
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");  
            props.put("mail.smtp.socketFactory.fallback", "false");  
        }
        
        return Session.getInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(login, password);
            }
        });
    }

    @Override
    public String toString() {
        return login;
    }
}
